package com.bodsite.rpc.thrift.server;

import java.lang.reflect.Constructor;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadedSelectorServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;

import com.bodsite.common.logger.Logger;
import com.bodsite.common.logger.LoggerFactory;
import com.bodsite.rpc.spring.schema.bean.Service;
import com.bodsite.rpc.thrift.expetion.RpcException;
import com.bodsite.rpc.thrift.expetion.RpcException.RPC_EXPECTION;

/**
 * thrift 服务端启动类
 * @author bod
 * 2017年4月13日上午10:21:38
 */
public class ThtiftServer {
	private final static Logger logger = LoggerFactory.getLogger(ThtiftServer.class);
	private final static int selectorThreads = 100;
	private final static int workerThreads = 500;
	private final Service service;
	
	public ThtiftServer(Service service) {
		this.service = service;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected void start(){
		new Thread(){
			@Override
			public void run() {
				try {
					//获取处理器构造方法
					Constructor con = service.getProcessor().getConstructor(service.getIface());
					//实例化处理器 - 传入实现类
					TProcessor p = (TProcessor) con.newInstance(service.getImpl());
					//传输通道 非堵塞
					TNonblockingServerSocket transport  = new TNonblockingServerSocket(service.getPort());
					//采用TThreadedSelectorServer网络模型
					TThreadedSelectorServer.Args args = new TThreadedSelectorServer.Args(transport);
					//按块传输
					args.transportFactory(new TFramedTransport.Factory());
					//压缩二进制传输协议
					args.protocolFactory(new TCompactProtocol.Factory());
					//设置处理器
					args.processor(p);
					args.selectorThreads(service.getSelectorThreads()>0?service.getSelectorThreads():selectorThreads);
					args.workerThreads(service.getWorkerThreads()>0?service.getWorkerThreads():workerThreads);
					TServer server = new TThreadedSelectorServer(args);
					if(service.getImpl()==null){
						throw new RpcException(RPC_EXPECTION.RPC_NOT_IMPL, service.getId());
					}
					logger.info(service.getImpl().getClass().getName()+" start!");
					//启动服务
					server.serve();
				}catch (Exception e) {
					logger.error(e.getMessage(),e);
				}
			}
			
		}.start();
	}
	
	
}
